home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 1.toast / pc / sample code / graphics 2d / translaterotate / translaterotate.p < prev    next >
Encoding:
Text File  |  2000-06-23  |  4.9 KB  |  171 lines

  1. {
  2.     File:        TranslateRotate.p
  3.  
  4.     Contains:    Many people are uncomfortable with Apple's fixed-point data types,
  5.                 because they can't be used with normal operator arithmetic and
  6.                 because their representation is not easily readable (though it
  7.                 is easily converted to integer types).  Here's something to show
  8.                 how simple it really is.
  9.     
  10.                 TranslateRotate does two-dimensional translation and rotations
  11.                 in word-size coordinates, using fixed-point math.  Each routine
  12.                 is passed info for a transform matrix which tells the routine what
  13.                 to do with the fPoint argument.  Each routine then does its thing
  14.                 on its fPoint argument, returning the new fPoint position.
  15.     
  16.                 The purpose of TranslateRotate is to provide a simple demo of the
  17.                 use of Fixed and Fract math in basic 2D transformations.  The
  18.                 procedures sacrifice speed for clarity in their use of intermediate
  19.                 variables, etc.
  20.     
  21.                 Fixed-point math has broad applications for speed-sensitive code,
  22.                 and is accurate enough for any screen graphics computations, if
  23.                 you are careful to perform your computations so as to minimize
  24.                 error propagation (do multiplications first, divisions last, for
  25.                 example).  There are few reasons to use floating point unless you
  26.                 demand error smaller than 2 to the -16.
  27.     
  28.                 For demonstration purposes, the two routines (one for rotation,
  29.                 one for translation) are called together from an MPW shell
  30.                 application.  The application prompts you for x,y translation
  31.                 values and a rotation value in radians.  It then calls a routine
  32.                 which first rotates and then translates the point.  Type rotation
  33.                 = 999 to escape the program.
  34.     
  35.                 Points are stored as fWords, which are of size WORD.
  36.  
  37.  
  38.     Written by: Billster    
  39.  
  40.     Copyright:    Copyright © 1991-1999 by Apple Computer, Inc., All Rights Reserved.
  41.  
  42.                 You may incorporate this Apple sample source code into your program(s) without
  43.                 restriction. This Apple sample source code has been provided "AS IS" and the
  44.                 responsibility for its operation is yours. You are not permitted to redistribute
  45.                 this Apple sample source code as "Apple sample source code" after having made
  46.                 changes. If you're going to re-distribute the source, we require that you make
  47.                 it clear in the source that the code was descended from Apple sample source
  48.                 code, but that you've made changes.
  49.  
  50.     Change History (most recent first):
  51.                 7/16/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  52.                 
  53.  
  54. }
  55.  
  56.  
  57. Program TranslateRotate;
  58.  
  59. uses FixMath,ToolUtils;
  60.  
  61. const
  62.     FracToIntegerConversion = 1073741824; { Divide by this to turn Frac into truncated int }
  63.     FixToIntegerConversion = 65536; { Divide by this to turn Fixed into truncated int }
  64.  
  65. type
  66.     fWord = integer;                { This is the type for linear measurement hereafter }
  67.     
  68.     fPoint = record                    { This is the type for an arbitrary point }
  69.         x : fWord;
  70.         y : fWord;
  71.     end;
  72.     
  73.     TransRot2D = record                { This record holds all the information for the }
  74.         x : fWord;                    {   transformation or rotation of a point }
  75.         y : fWord;
  76.         rot : Fixed;
  77.     end;
  78.  
  79.     TransRot3D = record                { This would hold the information for the }
  80.         x : fWord;                    {   translation/rotation in the 3D case. }
  81.         y : fWord;                    {   The routines are not implemented in this }
  82.         z : fWord;                    {    sample, however. }
  83.         rotXY : Fixed;
  84.         rotYZ : Fixed;
  85.         rotXZ : Fixed;
  86.     end;
  87.  
  88. var
  89.     transformInput        : transRot2D;
  90.     fPtInput, fPtResult    : fPoint;
  91.     radians : real;
  92.  
  93.  
  94.  
  95.  
  96.  
  97. { Routines for translation and rotation }
  98.  
  99.  
  100.  
  101. Function Rotate2D(theFPoint: fPoint; theTransRot : transRot2D) : fPoint;
  102. var
  103.     sinRot, cosRot: Fract;
  104. begin
  105.     sinRot := FracSin(theTransRot.rot);
  106.     cosRot := FracCos(theTransRot.rot);
  107.     
  108.     Rotate2D.x := fWord( FracMul(cosRot,theFPoint.x) - FracMul(sinRot,theFPoint.y) );
  109.     Rotate2D.y := fWord( FracMul(sinRot,theFPoint.x) + FracMul(cosRot,theFPoint.y) );
  110.     
  111.     { The above is a computation of:
  112.         
  113.         | cos(rot)  -sin(rot) |  | x |
  114.         |                      |  |   |
  115.         | sin(rot)  cos(rot)  |  | y |
  116.     }
  117. end;
  118.  
  119.  
  120.  
  121. Function Translate2D(theFPoint: fPoint; theTransRot : transRot2D) : fPoint;
  122. begin
  123.     Translate2D.x := theFPoint.x + theTransRot.x;
  124.     Translate2D.y := theFPoint.y + theTransRot.y;
  125.  
  126.     { The above is a computation of:
  127.         
  128.         | tranlate2D.x       0          |  | x |
  129.         |                               |  |   |
  130.         |      0        tranlate2D.y |  | y |
  131.     }
  132. end;
  133.  
  134.  
  135.  
  136.  
  137.  
  138. { Routines specific to the MPW Shell tool }
  139.  
  140.  
  141. Procedure Initialize;    { Start us off somewhere }
  142. begin
  143.     fPtInput.x := 100;
  144.     fPtInput.y := 100;
  145. end;
  146.  
  147.  
  148.  
  149. Function TransRotate2D(theFPoint: fPoint; theTransRot : transRot2D) : fPoint;
  150. { Calls Rotate2D, then Translate2D }
  151. begin
  152.     TransRotate2D := Translate2D(Rotate2D(theFPoint,theTransRot),theTransRot);
  153. end;
  154.  
  155.  
  156.  
  157. begin
  158.     Initialize;
  159.     repeat
  160.         write('X: ');
  161.         readln(transformInput.x);
  162.         write('Y: ');
  163.         readln(transformInput.y);
  164.         write('Rotation: ');
  165.         readln(radians);
  166.         transformInput.rot:=round(radians * FixToIntegerConversion);
  167.     
  168.         fPtResult := TransRotate2D(fPtInput, transformInput);
  169.         writeln('Output: ',fPtResult.x,fPtResult.y);
  170.     until transformInput.rot = (999 * FixToIntegerConversion)
  171. end.